<?php
class PapiWS_PersonalizedproductrendererController extends Ext_Controller_Action
{

	// image canvas
	private $canvas;

	public function renderproductfaceAction( )
	{

		dl('imagick.so');

        $productId = $this->getRequest()->getParam('personalizedProductId');
        if ( ! $productId ) {
			$productId = 210;
        }

        $faceNum = $this->getRequest()->getParam('faceNum');
        if ( ! $faceNum ) {
			$faceNum = 1;
        }

		$ppService = new PapiWS_Service_PersonalizedProduct();
		$product = $ppService->getProduct( $productId );

		// retrieve face definition
		$faceDefinition = $this->getFaceDefinition( $product, $faceNum );

		// TODO: verificar q $faceNum > 0
		$face = $product->faces[$faceNum - 1];

		// TODO: fix error reporting
		if ( $faceDefinition === null )
			die('No existe la informacion de esta carra!');

		// initialize image canvas
		$this->initImage( $faceDefinition );

		// remove background GO from list
		$goList = array();
		$bgObject = null;
		foreach( $face->graphicalObjects as $go ) {
			if ( $go instanceof PapiWS_Model_BackgroundVO ) {
				$bgObject = $go;
			} else {
				$goList[] = $go;
			}
		}

		// sort objects using Z index
		usort( $goList, array( get_class($this), 'zOrderCompare') );

		// render background
		$this->renderGraphicalObject( $bgObject );

		// render other graphical objects
		foreach( $goList as $go ) {
			$this->renderGraphicalObject( $go );
		}

		/* Output the image*/
		header("Content-Type: image/png");
		$this->canvas->setImageFormat('png');
		echo $this->canvas;
		die();
	}

	static function zOrderCompare($go1, $go2)
	{
		if ( $go1->z == $go2->z )
			return 0;
		return ($go1->z > $go2->z) ? +1 : -1;
	}


	private function renderGraphicalObject( $go ) {
		// render background
		if ( $go === null ) 
			return;

		switch ($go->type) {
			case PapiWS_Model_BackgroundVO::BACKGROUND_IMAGE:
			case PapiWS_Model_BackgroundVO::BACKGROUND_FILL:
				$renderer = new PapiWS_Model_BackgroundRenderer( $this->canvas );
				$renderer->render( $go );
				break;
			case PapiWS_Model_ShapeVO::SHAPE:
				$renderer = new PapiWS_Model_ShapeRenderer( $this->canvas );
				$renderer->render( $go );
				break;
			case PapiWS_Model_TextBoxVO::TEXT_BOX:
				$renderer = new PapiWS_Model_TextBoxRenderer( $this->canvas );
				$renderer->render( $go );
				break;
			default:
				break;
		}
	}

	private function initImage( $faceDefinition ) {

		$bbox = $faceDefinition->boundingBox;
		$widthPx  = $this->mmToPx( $bbox->width );
		$heightPx = $this->mmToPx( $bbox->height );

		// create a white image
		$this->canvas = new Imagick();
		$this->canvas->newImage( $widthPx, $heightPx, new ImagickPixel('white') );

	}

	private function getFaceDefinition( $product, $faceNum )
	{
		$faces = $product->templateProduct->faces;
		foreach( $faces as $face ) {
			if ( $face->faceOrder == $faceNum )
				return $face;
		}
		return null;
	}

	public function getCanvas()
	{
		return $this->canvas;
	}

	public static function mmToPx( $length )
	{
		// TODO get from conf. Take into account
		// the fact that output DPI != input DPI !!!!
		$dpi = 200;
		$lengthPx = $length * $dpi / 25.4;
		return (int) round( $lengthPx );
	}

}
